/**
 * 反射 枚举 lambda表达式
 */
class Student{
    //私有属性name
    private String name = "bit";
    //公有属性age
    public int age = 18;
    //不带参数的构造方法
    public Student(){
        System.out.println("Student()");
    }
    private Student(String name,int age) {
        this.name = name;
        this.age = age;
        System.out.println("Student(String,name)");
    }
    private void eat(){
        System.out.println("i am eat");
    }
    public void sleep(){
        System.out.println("i am pig");
    }
    private void function(String str) {
        System.out.println(str);
    }
    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}
interface NoParameterNoReturn {
    void test();
}
public class Test {
    /**
     * 反射
     * 枚举
     * lambda表达式
     * @param args
     */
    /**
     * lambda表达式
     */
    public static void main(String[] args) {
        /**
         *         优点：
         *         1. 代码简洁，开发迅速
         *         2. 方便函数式编程
         *         3. 非常容易进行并行计算
         *         4. Java 引入 Lambda，改善了集合操作
         *         缺点：
         *         1. 代码可读性变差
         *         2. 在非并行计算中，很多计算未必有传统的 for 性能要高
         *         3. 不容易进行调试
         */

    }
    public static void main13(String[] args) {
        /**
         * Lambda的变量捕获
         */
        int a = 10;
        NoParameterNoReturn noParameterNoReturn = ()->{
// a = 99; error
            System.out.println("捕获变量："+a);
        };
        noParameterNoReturn.test();
    }

    public static void main12(String[] args) {
        /**
         *  Lambda表达式的基本使用
             *  语法精简
             * 1. 参数类型可以省略，如果需要省略，每个参数的类型都要省略。
             * 2. 参数的小括号里面只有一个参数，那么小括号可以省略
             * 3. 如果方法体当中只有一句代码，那么大括号可以省略
             *  4. 如果方法体中只有一条语句，且是return语句，那么大括号可以省略，且去掉return关键字。
         */
    }
    public static void main11(String[] args) {
        /**
         * 背景
         * 基本语法: (parameters) -> expression 或 (parameters) ->{ statements; }
         * 函数式接口:函数式接口定义：一个接口有且只有一个抽象方法
         */
    }
    /**
     * 枚举的使用
     *      1.枚举的背景及定义
     *      2.使用
     *      3.枚举优缺点
     *      4.枚举和反射->反射拿不到枚举
     *      5.总结
     */
    public static void main10(String[] args) {
        /**
         * 总结
         *      优点:
         *          1.更简单,安全,
         *          2.具有内置类型,(优雅)
         *      缺点:
         *          不可继承 无法拓展
         */
    }
    public static void main9(String[] args) {
        /**
         * 使用:->TestEnum演示
         *      1.switch
         *      2.常用方法
         */
    }
    public static void main8(String[] args) {
        /**
         * 枚举的背景及定义->TestEnum演示
         *      语法:定义Enum类 ,枚举常量
         *      优点:将一组常量组织起来统一管理
         *      场景:颜色划分 错误码状态 消息类型
         */
    }
    /**
     * 反射
     * @param args
     *      1.定义
     *      2.用途
     *      3.反射基本信息
     *      4.反射相关的类
     *      5.反射的优缺点
     *      6.重点总结
     */
    public static void main7(String[] args) {
        /**
         * 重点总结:
         *      反射的意义
         *      反射重要的几个类
         *      学会合理使用反射
         */
    }
    public static void main6(String[] args) {
        /**
         * 反射的优缺点
         *      优点:
         *      1.对于任意一个类,都能知道这个类的属性和方法,对于任意一个对象,都能调用它任意方法
         *      2.增加灵活性和扩展性,降低耦合性,提高自适能力
         *      3.运用到了很多流行框架,Struts Hibernate Spring等
         *
         *      缺点:
         *      1.使用反射会有效率问题,导致程序效率降低
         *      2.带来维护问题
         */
    }
    /**
     * 反射相关的类
     *      class类(类/接口) Field类(成员属性) Method类(成员方法) Constructor类(构造方法)
     *      1.Class类
     *      2.反射示例
     */
    public static void main5(String[] args) {
        /**
         * 反射示例
         *      获取Class对象的方法->三种方法获取对象是同一个
         *           1.通过getClass获取Class对象
         *           2.直接通过 类名.class
         *           3、通过 Class 对象的 forName() 静态方法来获取
         *      反射的使用->ReflectClassDemo
         */
        /*
        1.通过getClass获取Class对象
        */
        Student s1 = new Student();
        Class c1 = s1.getClass();
        /*
        2.直接通过 类名.class 的方式得到,该方法最为安全可靠，程序性能更高
        这说明任何一个类都有一个隐含的静态成员变量 class
        */
        Class c2 = Student.class;
        /*
        3、通过 Class 对象的 forName() 静态方法来获取，用的最多，
        但可能抛出 ClassNotFoundException 异常
        */
        Class c3 = null;
        //注意这里是类的全路径，如果有包需要加包的路径
        //一个类在 JVM 中只会有一个 Class 实例,即我们对上面获取的
        //c1,c2,c3进行 equals 比较，发现都是true
        System.out.println(c1.equals(c2));
        System.out.println(c1.equals(c3));
        System.out.println(c2.equals(c3));
    }
    public static void main4(String[] args) {
        /**
         * Class类的方法
         *      获取类相关的方法
         *      获取成员属性相关的方法
         *      获取成员方法的方法
         *      获取构造方法的方法
         */
    }
    public static void main3(String[] args) {
        /**
         * 反射基本信息
         *      java运行时出现的两种类型:运行时类型 编译时类型
         *      通过反射程序可以判断出对象和方法属于哪些类
         */
    }
    public static void main2(String[] args) {
        /**
         * 用途
         *      1.获取类/成员变量...
         *      2.开发各种通用框架
         */
    }
    public static void main1(String[] args) {
        /**
         * 定义:在运行状态中,对于任意一个类,
         * 都能知道这个类的所有属性和方法...能拿到,并且能进行修改
         * 这种动态获取信息以及动态调用对象方法的功能称为反射机制1
         */
    }
}
